// videostream.h
#ifndef VIDEOSTREAM_H
#define VIDEOSTREAM_H

#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QTimer>
#include <QImage>
#include <QDateTime>
#include <atomic>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}

enum class ThreadState {
    Stopped,
    Initializing,
    Running
};

// customvideostream.h
#define SAFE_UNREF(pkt) \
    do { \
        if ((pkt)->buf && av_buffer_get_ref_count((pkt)->buf) > 0) { \
            av_packet_unref(pkt); \
        } else if ((pkt)->data) { \
            av_packet_unref(pkt); \
        } \
    } while(0)

class VideoStream : public QThread
{
    Q_OBJECT
public:
    explicit VideoStream(QObject *parent = nullptr);
    ~VideoStream() override;

    bool open(const QString &url);
    void close();
    void setFps(int fps) { targetFps = fps; }
    bool isRunning() const { return threadState.load() == ThreadState::Running; }
    bool is8In1Frame(const QImage &frame);

    QImage captureFrame();

signals:
    void frameReady(QImage frame);
    void resolutionChanged(int width, int height);
    void sendVideoinitialized(bool success);
    void connectserverfailed();
    void frameRateUpdated(double fps);
protected:
    void run() override;

private:
    // FFmpeg上下文
    struct StreamContext {
        AVFormatContext *formatCtx = nullptr;
        AVCodecContext *codecCtx = nullptr;
        SwsContext *swsCtx = nullptr;
        int videoStreamIndex = -1;
        std::atomic<bool> interruptFlag{false};
    };

    bool initStream();
    void safeCleanup();
    QImage convertFrame(AVFrame *frame) const;
    void scheduleRetry();
    QString avErrorString(int errnum);
    bool reinitAfterStreamChange();

    QMutex mutex;
    QString currentUrl;
    StreamContext ctx;
    std::atomic<ThreadState> threadState{ThreadState::Stopped};
    std::atomic<bool>interruptFlag;
    int targetFps = 30;
    int retryCount = 0;
    const int maxRetries = 3;
    const int retryInterval = 2000;

    // 帧率计算
    QMutex captureMutex;
    QWaitCondition condition;
    QImage cachedFrame;

    // 帧捕获缓存
    qint64 lastTimeMs = 0;
    int frameCount = 0;
};

#endif // VIDEOSTREAM_H
